#!/usr/bin/env python
#coding: utf-8
'''
Created on 2017年2月17日

@author: Administrator
'''
import linecache
import traceback
from common.tasks import stats_mail_send
from django.conf import settings
from django.utils.log import AdminEmailHandler
from django.views.debug import ExceptionReporter, get_exception_reporter_filter
from scrapy import signals
from common.tasks import mail_admins
from scrapy.exceptions import NotConfigured


class AdminCeleryEmailHandler(AdminEmailHandler):
    """An exception log handler that emails log entries to site admins.

    If the request is passed as the first argument to the log record,
    request data will be provided in the email report.
    """

    def emit(self, record):
        try:
            request = record.request
            subject = '%s (%s IP): %s' % (
                record.levelname,
                ('internal' if request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS
                 else 'EXTERNAL'),
                record.getMessage()
            )
            filter = get_exception_reporter_filter(request)
            request_repr = filter.get_request_repr(request)
        except Exception:
            subject = '%s: %s' % (
                record.levelname,
                record.getMessage()
            )
            request = None
            request_repr = "Request repr() unavailable."
        subject = self.format_subject(subject)

        if record.exc_info:
            exc_info = record.exc_info
            stack_trace = '\n'.join(traceback.format_exception(*record.exc_info))
        else:
            exc_info = (None, record.getMessage(), None)
            stack_trace = 'No stack trace available'

        message = "%s\n\n%s" % (stack_trace, request_repr)
        reporter = ExceptionReporter(request, is_email=True, *exc_info)
        html_message = reporter.get_traceback_html() if self.include_html else None
        mail_admins.delay(subject, message, fail_silently=True,html_message=html_message,connection=None)


class AdminStatsMailerHandler(object):
    
    def __init__(self, stats, recipients):
        self.stats = stats
        self.recipients = recipients
    
    @classmethod
    def from_crawler(cls, crawler):
        recipients = crawler.settings.getlist("STATSMAILER_RCPTS")
        if not recipients:
            raise NotConfigured
        o = cls(crawler.stats, recipients)
        crawler.signals.connect(o.spider_error, signal=signals.spider_error)
        return o
    
    def spider_error(self, spider, failure):
        body = "Traceback (most recent call last):\n"
        for method, filename, lineno, localVars, globalVars in failure.frames:
            body += '  File "%s", line %s, in %s\n' % (filename, lineno, method)
            body += '    %s\n' % linecache.getline(filename, lineno).strip()
        stats_mail_send.delay(self.recipients, "Scrapy stats for: %s" % spider.name, body)